#ifndef RESIZERHANDLESTRATEGY_H
#define RESIZERHANDLESTRATEGY_H

#pragma once

#include "../../ToolkitLayer.h"
#include "../Behaviors/DraggingResizerStrategy.h"


/**
 * This strategy extends the DraggingResizerStrategy by providing a visual
 * handle to allow resizing a component. The handle is located in the lower
 * right corner of the component bounds. When it is dragged, the component
 * is resized having the upper left corner as a fixed point.
 *
 * @author Fabricio Anastacio - fabriciocfa@yahoo.com
 * @since August 8, 2007
 */
class TOOLKITLAYER_API ResizerHandleStrategy : public DraggingResizerStrategy
{
	// Attributes
protected:
	/** The color of the resizing handle. */
	float color[4];
	/** The color of the handle of the selected component. */
	float colorSelected[4];
	/** The displacement to be used for rendering the handle. */
	float displacement;
	/** The line width used to draw the handle. */
	float handleWidth;

	/** The display list identifier. */
	unsigned int dlHandle;
	/** The picking display list identifier. */
	unsigned int dlHandlePicking;
	/** The width value currently used by the display list. */
	unsigned int dlWidth;
	/** The height value currently used by the display list. */
	unsigned int dlHeight;
	/** The scaleX value currently used by the display list. */
	float dlScaleX;
	/** The scaleY value currently used by the display list. */
	float dlScaleY;
	

	// Methods
public:
	/**
	 * Constructs a strategy with a resizer handle.
	 */
	ResizerHandleStrategy(void);
	/**
	 * Destroys this strategy.
	 */
	~ResizerHandleStrategy(void);


	// ACCESSOR METHODS
	/**
	 * Returns the color used to draw the handle (using an array of 4 floats).
	 *
	 * @return the color used to draw the handle.
	 */
	inline float* getColor() { return color; };
	/**
	 * Sets the color to be used for drawing the handle (using an array of 4
	 * floats).
	 *
	 * @param c the color to be used for drawing the handle.
	 */
	inline void setColor(float* c) {
		color[0] = c[0]; color[1] = c[1]; color[2] = c[2]; color[3] = c[3];
	};
	/**
	 * Returns the color used to draw the selected handle (using an array of 4
	 * floats).
	 *
	 * @return the color used to draw the selected handle.
	 */
	inline float* getSelectedColor() { return colorSelected; };
	/**
	 * Sets the color to be used for drawing the selected handle (using an
	 * array of 4 floats).
	 *
	 * @param c the color to be used for drawing the selected handle.
	 */
	inline void setSelectedColor(float* c) {
		colorSelected[0] = c[0]; colorSelected[1] = c[1]; colorSelected[2] = c[2];
		colorSelected[3] = c[3];
	};
	/**
	 * Returns the value of the handle displacement.
	 *
	 * @return the value of the handle displacement.
	 */
	inline float getDisplacement() { return displacement; };
	/**
	 * Sets the value of the handle displacement.
	 *
	 * @param f the value to be used as the handle displacement.
	 */
	inline void setDisplacement(float d) { displacement = d; };
	

protected:
	/**
	 * Creates the display list to draw this handle.
	 */
	void createDisplayList();

	/**
	 * Defines the drawing strategy for the associated component.
	 *
	 * @param enablePicking if true, draw for selection mode (adding the
	 * component id).
	 */
	void draw(const std::vector<unsigned long>& selectedIds);
	/**
	 * Defines the drawing strategy for the associated component that should be
	 * used for picking.
	 */
	void drawForPicking();
	/**
	 * Handles the given event.
	 *
	 * @param evt the event to be handled.
	 */
	void onEvent(LargeDisplayEvent* evt);
	/**
	 * Defines the strategy to be used when the associated component is
	 * "dropped" inside another component (likely, a container). It is called
	 * when the component is processed from the manager's update list. It
	 * usually defines some "decorative" behavior such as triggering
	 * animations, since the composition structure is already managed by the
	 * LargeDisplayManager class. Returns true if this call resulted in
	 * adding the component to a container with animation.
	 *
	 * @param parentChanged true if the component's parent changed with the
	 * dropping.
	 * @return true if this call resulted in adding or keeping the component to
	 * a container with animation, false otherwise.
	 */
	bool drop(bool parentChanged);
	
};

#endif // RESIZERHANDLESTRATEGY_H
